<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Perfect hash function</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Perfect_hash_function"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.math.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Perfect_hash_function rootpage-Perfect_hash_function skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Perfect hash function</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<p>In <a href="Computer_science" title="Computer science">computer science</a>, a <b>perfect hash function</b> <span class="texhtml mvar" style="font-style:italic;">h</span> for a set <span class="texhtml mvar" style="font-style:italic;">S</span> is a <a href="Hash_function" title="Hash function">hash function</a> that maps distinct elements in <span class="texhtml mvar" style="font-style:italic;">S</span> to a set of <span class="texhtml mvar" style="font-style:italic;">m</span> integers, with no <a href="Hash_collision" title="Hash collision">collisions</a>. In mathematical terms, it is an <a href="Injective_function" title="Injective function">injective function</a>.
</p><p>Perfect hash functions may be used to implement a <a href="Lookup_table" title="Lookup table">lookup table</a> with constant worst-case access time. A perfect hash function can, as any <a href="Hash_function" title="Hash function">hash function</a>, be used to implement <a href="Hash_table" title="Hash table">hash tables</a>, with the advantage that no <a href="Hash_table#Collision_resolution" title="Hash table">collision resolution</a> has to be implemented. In addition, if the keys are not in the data and if it is known that queried keys will be valid, then the keys do not need to be stored in the lookup table, saving space.
</p><p>Disadvantages of perfect hash functions are that <span class="texhtml mvar" style="font-style:italic;">S</span> needs to be known for the construction of the perfect hash function. Non-dynamic perfect hash functions need to be re-constructed if <span class="texhtml mvar" style="font-style:italic;">S</span> changes. For frequently changing <span class="texhtml mvar" style="font-style:italic;">S</span> <a href="Dynamic_perfect_hashing" title="Dynamic perfect hashing">dynamic perfect hash functions</a> may be used at the cost of additional space.<sup id="cite_ref-DynamicPerfectHashing_1-0" class="reference"><a href="#cite_note-DynamicPerfectHashing-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> The space requirement to store the perfect hash function is in <span class="texhtml"><i>O</i>(<i>n</i>)</span> where <span class="texhtml"><i>n</i></span> is the number of keys in the structure.
</p><p>The important performance parameters for perfect hash functions are the evaluation time, which should be constant, the construction time, and the representation size.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Application">Application</h2></div>
<p>A perfect hash function with values in a limited range can be used for efficient lookup operations, by placing keys from <span class="texhtml mvar" style="font-style:italic;">S</span> (or other associated values) in a <a href="Lookup_table" title="Lookup table">lookup table</a> indexed by the output of the function. One can then test whether a key is present in <span class="texhtml mvar" style="font-style:italic;">S</span>, or look up a value associated with that key, by looking for it at its cell of the table. Each such lookup takes <a href="Constant_time" class="mw-redirect" title="Constant time">constant time</a> in the <a href="Worst-case_complexity" title="Worst-case complexity">worst case</a>.<sup id="cite_ref-inventor_2-0" class="reference"><a href="#cite_note-inventor-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup> With perfect hashing, the associated data can be read or written with a single access to the table.<sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Performance_of_perfect_hash_functions">Performance of perfect hash functions</h2></div>
<p>The important performance parameters for perfect hashing are the representation size, the evaluation time, the construction time, and additionally the range requirement <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle {\frac {m}{n}}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mi>m</mi>
<mi>n</mi>
</mfrac>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle {\frac {m}{n}}}</annotation>
</semantics>
</math></span><img src="./d48d87468620ad6c70385ddd0d024577ccb559e1.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -1.838ex; width:2.877ex; height:4.676ex;" alt="{\displaystyle {\frac {m}{n}}}" loading="lazy"></span> (average number of buckets per key in the hash table).<sup id="cite_ref-CHD_4-0" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup> The evaluation time can be as fast as <span class="texhtml"><i>O</i>(<i>1</i>)</span>, which is optimal.<sup id="cite_ref-inventor_2-1" class="reference"><a href="#cite_note-inventor-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-CHD_4-1" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup> The construction time needs to be at least <span class="texhtml"><i>O</i>(<i>n</i>)</span>, because each element in <span class="texhtml mvar" style="font-style:italic;">S</span> needs to be considered, and <span class="texhtml mvar" style="font-style:italic;">S</span> contains <span class="texhtml mvar" style="font-style:italic;">n</span> elements. This lower bound can be achieved in practice.<sup id="cite_ref-CHD_4-2" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>The lower bound for the representation size depends on <span class="texhtml mvar" style="font-style:italic;">m</span> and <span class="texhtml mvar" style="font-style:italic;">n</span>. Let <span class="texhtml"><i>m</i> = (1+ε) <i>n</i></span> and <span class="texhtml mvar" style="font-style:italic;">h</span> a perfect hash function. A good approximation for the lower bound is <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \log e-\varepsilon \log {\frac {1+\varepsilon }{\varepsilon }}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>log</mi>
<mo><!-- --></mo>
<mi>e</mi>
<mo>−<!-- − --></mo>
<mi>ε<!-- ε --></mi>
<mi>log</mi>
<mo><!-- --></mo>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mrow>
<mn>1</mn>
<mo>+</mo>
<mi>ε<!-- ε --></mi>
</mrow>
<mi>ε<!-- ε --></mi>
</mfrac>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \log e-\varepsilon \log {\frac {1+\varepsilon }{\varepsilon }}}</annotation>
</semantics>
</math></span><img src="./b02a088abd50352f229055b2573a6cb24e70ea05.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -1.838ex; width:18.035ex; height:5.176ex;" alt="{\displaystyle \log e-\varepsilon \log {\frac {1+\varepsilon }{\varepsilon }}}" loading="lazy"></span> Bits per element. For minimal perfect hashing, <span class="texhtml">ε = 0</span>, the lower bound is <span class="texhtml">log e ≈ 1.44</span> bits per element.<sup id="cite_ref-CHD_4-3" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Construction">Construction</h2></div>
<p>A perfect hash function for a specific set <span class="texhtml mvar" style="font-style:italic;">S</span> that can be evaluated in constant time, and with values in a small range, can be found by a <a href="Randomized_algorithm" title="Randomized algorithm">randomized algorithm</a> in a number of operations that is proportional to the size of S.
The original construction of <a href="#CITEREFFredmanKomlósSzemerédi1984">Fredman, Komlós & Szemerédi (1984)</a> uses a two-level scheme to map a set <span class="texhtml mvar" style="font-style:italic;">S</span> of <span class="texhtml mvar" style="font-style:italic;">n</span> elements to a range of <span class="texhtml"><i>O</i>(<i>n</i>)</span> indices, and then map each index to a range of hash values. The first level of their construction chooses a large prime <span class="texhtml mvar" style="font-style:italic;">p</span> (larger than the size of the <a href="Universe_(mathematics)" title="Universe (mathematics)">universe</a> from which <span class="texhtml mvar" style="font-style:italic;">S</span> is drawn), and a parameter <span class="texhtml mvar" style="font-style:italic;">k</span>, and maps each element <span class="texhtml mvar" style="font-style:italic;">x</span> of <span class="texhtml mvar" style="font-style:italic;">S</span> to the index
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle g(x)=(kx{\bmod {p}}){\bmod {n}}.}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>g</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mo stretchy="false">(</mo>
<mi>k</mi>
<mi>x</mi>
<mrow class="MJX-TeXAtom-ORD">
<mo lspace="thickmathspace" rspace="thickmathspace">mod</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>p</mi>
</mrow>
</mrow>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mo lspace="thickmathspace" rspace="thickmathspace">mod</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>n</mi>
</mrow>
</mrow>
<mo>.</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle g(x)=(kx{\bmod {p}}){\bmod {n}}.}</annotation>
</semantics>
</math></span><img src="./0eed5c339f42fdccc1685d8d3b1af928e2a3be01.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:26.277ex; height:2.843ex;" alt="{\displaystyle g(x)=(kx{\bmod {p}}){\bmod {n}}.}" loading="lazy"></span></dd></dl>
<p>If <span class="texhtml mvar" style="font-style:italic;">k</span> is chosen randomly, this step is likely to have collisions, but the number of elements <span class="texhtml mvar" style="font-style:italic;">n<sub>i</sub></span> that are simultaneously mapped to the same index <span class="texhtml mvar" style="font-style:italic;">i</span> is likely to be small.
The second level of their construction assigns disjoint ranges of <span class="texhtml"><i>O</i>(<i>n<sub>i</sub></i><sup>2</sup>)</span> integers to each index <span class="texhtml mvar" style="font-style:italic;">i</span>. It uses a second set of linear modular functions, one for each index <span class="texhtml mvar" style="font-style:italic;">i</span>, to map each member <span class="texhtml mvar" style="font-style:italic;">x</span> of <span class="texhtml mvar" style="font-style:italic;">S</span> into the range associated with <span class="texhtml"><i>g</i>(<i>x</i>)</span>.<sup id="cite_ref-inventor_2-2" class="reference"><a href="#cite_note-inventor-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p><p>As <a href="#CITEREFFredmanKomlósSzemerédi1984">Fredman, Komlós & Szemerédi (1984)</a> show, there exists a choice of the parameter <span class="texhtml mvar" style="font-style:italic;">k</span> such that the sum of the lengths of the ranges for the <span class="texhtml mvar" style="font-style:italic;">n</span> different values of <span class="texhtml"><i>g</i>(<i>x</i>)</span> is <span class="texhtml"><i>O</i>(<i>n</i>)</span>. Additionally, for each value of <span class="texhtml"><i>g</i>(<i>x</i>)</span>, there exists a linear modular function that maps the corresponding subset of <span class="texhtml mvar" style="font-style:italic;">S</span> into the range associated with that value. Both <span class="texhtml mvar" style="font-style:italic;">k</span>, and the second-level functions for each value of <span class="texhtml"><i>g</i>(<i>x</i>)</span>, can be found in <a href="Polynomial_time" class="mw-redirect" title="Polynomial time">polynomial time</a> by choosing values randomly until finding one that works.<sup id="cite_ref-inventor_2-3" class="reference"><a href="#cite_note-inventor-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p><p>The hash function itself requires storage space <span class="texhtml"><i>O</i>(<i>n</i>)</span> to store <span class="texhtml mvar" style="font-style:italic;">k</span>, <span class="texhtml mvar" style="font-style:italic;">p</span>, and all of the second-level linear modular functions. Computing the hash value of a given key <span class="texhtml mvar" style="font-style:italic;">x</span> may be performed in constant time by computing <span class="texhtml"><i>g</i>(<i>x</i>)</span>, looking up the second-level function associated with <span class="texhtml"><i>g</i>(<i>x</i>)</span>, and applying this function to <span class="texhtml mvar" style="font-style:italic;">x</span>.
A modified version of this two-level scheme with a larger number of values at the top level can be used to construct a perfect hash function that maps <span class="texhtml mvar" style="font-style:italic;">S</span> into a smaller range of length <span class="texhtml"><i>n</i> + <i>o</i>(<i>n</i>)</span>.<sup id="cite_ref-inventor_2-4" class="reference"><a href="#cite_note-inventor-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p><p>A more recent method for constructing a perfect hash function is described by <a href="#CITEREFBelazzouguiBotelhoDietzfelbinger2009">Belazzougui, Botelho & Dietzfelbinger (2009)</a> as "hash, displace, and compress". Here a first-level hash function <span class="texhtml mvar" style="font-style:italic;">g</span> is also used to map elements onto a range of <span class="texhtml mvar" style="font-style:italic;">r</span> integers. An element <span class="texhtml"><i>x</i> ∈ <i>S</i></span> is stored in the Bucket <span class="texhtml mvar" style="font-style:italic;">B<sub>g(x)</sub></span>.<sup id="cite_ref-CHD_4-4" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>Then, in descending order of size, each bucket's elements are hashed by a hash function of a sequence of independent fully random hash functions <span class="texhtml">(Φ<sub>1</sub>, Φ<sub>2</sub>, Φ<sub>3</sub>, ...)</span>, starting with <span class="texhtml">Φ<sub>1</sub></span>. If the hash function does not produce any collisions for the bucket, and the resulting values are not yet occupied by other elements from other buckets, the function is chosen for that bucket. If not, the next hash function in the sequence is tested.<sup id="cite_ref-CHD_4-5" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>To evaluate the perfect hash function <span class="texhtml"><i>h</i>(<i>x</i>)</span> one only has to save the mapping σ of the bucket index <span class="texhtml"><i>g</i>(<i>x</i>)</span> onto the correct hash function in the sequence, resulting in <span class="texhtml">h(x) = Φ<sub>σ(g(x))</sub></span>.<sup id="cite_ref-CHD_4-6" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>Finally, to reduce the representation size, the (<span class="texhtml">σ(i))<sub>0 ≤ i < r</sub></span> are compressed into a form that still allows the evaluation in <span class="texhtml"><i>O</i>(<i>1</i>)</span>.<sup id="cite_ref-CHD_4-7" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>This approach needs linear time in <span class="texhtml mvar" style="font-style:italic;">n</span> for construction, and constant evaluation time. The representation size is in <span class="texhtml"><i>O</i>(<i>n</i>)</span>, and depends on the achieved range. For example, with <span class="texhtml"><i>m</i> = 1.23<i>n</i></span> <a href="#CITEREFBelazzouguiBotelhoDietzfelbinger2009">Belazzougui, Botelho & Dietzfelbinger (2009)</a> achieved a representation size between 3.03 bits/key and 1.40 bits/key for their given example set of 10 million entries, with lower values needing a higher computation time. The space lower bound in this scenario is 0.88 bits/key.<sup id="cite_ref-CHD_4-8" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p>
<style data-mw-deduplicate="TemplateStyles:r1305433154">
/* start https://en.wikipedia.org/ */
.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}
/* end https://en.wikipedia.org/ */
</style>
<div class="mw-heading mw-heading3"><h3 id="Pseudocode">Pseudocode</h3></div>
<pre><b>algorithm</b> <i>hash, displace, and compress</i> <b>is</b>
(1) Split S into buckets <span class="texhtml">B<sub>i</sub> := g<sup>−1</sup>({i})∩S,0 ≤ i < r</span>
(2) Sort buckets B<sub>i</sub> in falling order according to size |B<sub>i</sub>|
(3) Initialize array T[0...m-1] with 0's
(4) <b>for all</b> i<span style="white-space: nowrap;"> </span>∈[r], in the order from (2), <b>do</b>
(5) <b>for</b> l<span style="white-space: nowrap;"> </span>←<span style="white-space: nowrap;"> </span>1,2,...
(6) <b>repeat</b> forming K<sub>i</sub><span style="white-space: nowrap;"> </span>←<span style="white-space: nowrap;"> </span>{<span class="texhtml">Φ</span><sub>l</sub>(x)|x<span style="white-space: nowrap;"> </span>∈<span style="white-space: nowrap;"> </span>B<sub>i</sub>}
(6) <b>until</b> |K<sub>i</sub>|=|B<sub>i</sub>| <b>and</b> K<sub>i</sub>∩{j|T[j]=1}=<span style="white-space: nowrap;"> </span>∅
(7) <b>let</b> σ(i):= the successful l
(8) <b>for all</b> j<span style="white-space: nowrap;"> </span>∈<span style="white-space: nowrap;"> </span>K<sub>i</sub> <b>let</b> T[j]:=<span style="white-space: nowrap;"> </span>1
(9) Transform (σ<sub>i</sub>)<sub>0≤i<r</sub> into compressed form, retaining <span class="texhtml"><i>O</i>(<i>1</i>)</span> access.
</pre>
<div class="mw-heading mw-heading2"><h2 id="Space_lower_bounds">Space lower bounds</h2></div>
<p>The use of <span class="texhtml"><i>O</i>(<i>n</i>)</span> words of information to store the function of <a href="#CITEREFFredmanKomlósSzemerédi1984">Fredman, Komlós & Szemerédi (1984)</a> is near-optimal: any perfect hash function that can be calculated in constant time
requires at least a number of bits that is proportional to the size of <span class="texhtml mvar" style="font-style:italic;">S</span>.<sup id="cite_ref-5" class="reference"><a href="#cite_note-5"><span class="cite-bracket">[</span>5<span class="cite-bracket">]</span></a></sup>
</p><p>For minimal perfect hash functions the information theoretic space lower bound is
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \log _{2}e\approx 1.44}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>log</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mo><!-- --></mo>
<mi>e</mi>
<mo>≈<!-- ≈ --></mo>
<mn>1.44</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \log _{2}e\approx 1.44}</annotation>
</semantics>
</math></span><img src="./0fd72ec3b460d6cf5434f1a0bb5bb5d24b4b2d15.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.729ex; height:2.676ex;" alt="{\displaystyle \log _{2}e\approx 1.44}" loading="lazy"></span></dd></dl>
<p>bits/key.<sup id="cite_ref-CHD_4-9" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p><p>For perfect hash functions, it is first assumed that the range of <span class="texhtml mvar" style="font-style:italic;">h</span> is bounded by <span class="texhtml mvar" style="font-style:italic;">n</span> as <span class="texhtml"><i>m</i> = (1+ε) <i>n</i></span>. With the formula given by <a href="#CITEREFBelazzouguiBotelhoDietzfelbinger2009">Belazzougui, Botelho & Dietzfelbinger (2009)</a> and for a <a href="Universe_(mathematics)" title="Universe (mathematics)">universe</a> <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle U\supseteq S}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>U</mi>
<mo>⊇<!-- ⊇ --></mo>
<mi>S</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle U\supseteq S}</annotation>
</semantics>
</math></span><img src="./16992fcab6da9089922e110403a580e2df030419.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.505ex; width:6.38ex; height:2.343ex;" alt="{\displaystyle U\supseteq S}" loading="lazy"></span> whose size <span class="texhtml">|<i>U</i>| = <i>u</i></span> tends towards infinity, the space lower bounds is
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \log _{2}e-\varepsilon \log {\frac {1+\varepsilon }{\varepsilon }}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>log</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mo><!-- --></mo>
<mi>e</mi>
<mo>−<!-- − --></mo>
<mi>ε<!-- ε --></mi>
<mi>log</mi>
<mo><!-- --></mo>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mrow>
<mn>1</mn>
<mo>+</mo>
<mi>ε<!-- ε --></mi>
</mrow>
<mi>ε<!-- ε --></mi>
</mfrac>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \log _{2}e-\varepsilon \log {\frac {1+\varepsilon }{\varepsilon }}}</annotation>
</semantics>
</math></span><img src="./776f6c7e58c34f514e1be99b98abdf9f15e14e2a.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -1.838ex; width:19.089ex; height:5.176ex;" alt="{\displaystyle \log _{2}e-\varepsilon \log {\frac {1+\varepsilon }{\varepsilon }}}" loading="lazy"></span></dd></dl>
<p>bits/key, minus <span class="texhtml">log(<i>n</i>)</span> bits overall.<sup id="cite_ref-CHD_4-10" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Extensions">Extensions</h2></div>
<div class="mw-heading mw-heading3"><h3 id="Dynamic_perfect_hashing">Dynamic perfect hashing</h3></div>
<style data-mw-deduplicate="TemplateStyles:r1236090951">
/* start https://en.wikipedia.org/ */
.mw-parser-output .hatnote{font-style:italic}.mw-parser-output div.hatnote{padding-left:1.6em;margin-bottom:0.5em}.mw-parser-output .hatnote i{font-style:normal}.mw-parser-output .hatnote+link+.hatnote{margin-top:-0.5em}@media print{body.ns-0 .mw-parser-output .hatnote{display:none!important}}
/* end https://en.wikipedia.org/ */
</style><div role="note" class="hatnote navigation-not-searchable">Main article: <a href="Dynamic_perfect_hashing" title="Dynamic perfect hashing">Dynamic perfect hashing</a></div>
<p>Using a perfect hash function is best in situations where there is a frequently queried large set, <span class="texhtml mvar" style="font-style:italic;">S</span>, which is seldom updated. This is because any modification of the set <span class="texhtml mvar" style="font-style:italic;">S</span> may cause the hash function to no longer be perfect for the modified set. Solutions which update the hash function any time the set is modified are known as <a href="Dynamic_perfect_hashing" title="Dynamic perfect hashing">dynamic perfect hashing</a>,<sup id="cite_ref-DynamicPerfectHashing_1-1" class="reference"><a href="#cite_note-DynamicPerfectHashing-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> but these methods are relatively complicated to implement.
</p>
<div class="mw-heading mw-heading3"><h3 id="Minimal_perfect_hash_function">Minimal perfect hash function</h3></div>
<p>A minimal perfect hash function is a perfect hash function that maps <span class="texhtml mvar" style="font-style:italic;">n</span> keys to <span class="texhtml mvar" style="font-style:italic;">n</span> consecutive integers – usually the numbers from <span class="texhtml">0</span> to <span class="texhtml"><i>n</i> − 1</span> or from <span class="texhtml">1</span> to <span class="texhtml mvar" style="font-style:italic;">n</span>. A more formal way of expressing this is: Let <span class="texhtml mvar" style="font-style:italic;">j</span> and <span class="texhtml mvar" style="font-style:italic;">k</span> be elements of some finite set <span class="texhtml mvar" style="font-style:italic;">S</span>. Then <span class="texhtml mvar" style="font-style:italic;">h</span> is a minimal perfect hash function if and only if <span class="texhtml"><i>h</i>(<i>j</i>) = <i>h</i>(<i>k</i>)</span> implies <span class="texhtml"><i>j</i> = <i>k</i></span> (<a href="Injectivity" class="mw-redirect" title="Injectivity">injectivity</a>) and there exists an integer <span class="texhtml mvar" style="font-style:italic;">a</span> such that the range of <span class="texhtml mvar" style="font-style:italic;">h</span> is <span class="texhtml"><i>a</i>..<i>a</i> + |<i>S</i>| − 1</span>. It has been proven that a general purpose minimal perfect hash scheme requires at least <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \log _{2}e\approx 1.44}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>log</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mo><!-- --></mo>
<mi>e</mi>
<mo>≈<!-- ≈ --></mo>
<mn>1.44</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \log _{2}e\approx 1.44}</annotation>
</semantics>
</math></span><img src="./0fd72ec3b460d6cf5434f1a0bb5bb5d24b4b2d15.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.729ex; height:2.676ex;" alt="{\displaystyle \log _{2}e\approx 1.44}" loading="lazy"></span> bits/key.<sup id="cite_ref-CHD_4-11" class="reference"><a href="#cite_note-CHD-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup> Assuming that <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle S}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>S</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle S}</annotation>
</semantics>
</math></span><img src="./4611d85173cd3b508e67077d4a1252c9c05abca2.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.499ex; height:2.176ex;" alt="{\displaystyle S}" loading="lazy"></span> is a set of size <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle n}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>n</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle n}</annotation>
</semantics>
</math></span><img src="./a601995d55609f2d9f5e233e36fbe9ea26011b3b.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.395ex; height:1.676ex;" alt="{\displaystyle n}" loading="lazy"></span> containing integers in the range <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle [1,2^{o(n)}]}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo stretchy="false">[</mo>
<mn>1</mn>
<mo>,</mo>
<msup>
<mn>2</mn>
<mrow class="MJX-TeXAtom-ORD">
<mi>o</mi>
<mo stretchy="false">(</mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mrow>
</msup>
<mo stretchy="false">]</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle [1,2^{o(n)}]}</annotation>
</semantics>
</math></span><img src="./f0ac67d15f0cd602c935e60c92e1d2cf4bb68bff.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:7.948ex; height:3.343ex;" alt="{\displaystyle [1,2^{o(n)}]}" loading="lazy"></span>, it is known how to efficiently construct an explicit minimal perfect hash function from <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle S}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>S</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle S}</annotation>
</semantics>
</math></span><img src="./4611d85173cd3b508e67077d4a1252c9c05abca2.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.499ex; height:2.176ex;" alt="{\displaystyle S}" loading="lazy"></span> to <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \{1,2,\ldots ,n\}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo fence="false" stretchy="false">{</mo>
<mn>1</mn>
<mo>,</mo>
<mn>2</mn>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<mi>n</mi>
<mo fence="false" stretchy="false">}</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \{1,2,\ldots ,n\}}</annotation>
</semantics>
</math></span><img src="./4ebfec86b3f22a18f086275390917d5aaa2d8c22.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.257ex; height:2.843ex;" alt="{\displaystyle \{1,2,\ldots ,n\}}" loading="lazy"></span> that uses space <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle n\log _{2}e+o(n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>n</mi>
<msub>
<mi>log</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mo><!-- --></mo>
<mi>e</mi>
<mo>+</mo>
<mi>o</mi>
<mo stretchy="false">(</mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle n\log _{2}e+o(n)}</annotation>
</semantics>
</math></span><img src="./09277f1ba7d62f18c983de0af01dd3deea037948.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:14.45ex; height:2.843ex;" alt="{\displaystyle n\log _{2}e+o(n)}" loading="lazy"></span>bits and that supports constant evaluation time.<sup id="cite_ref-6" class="reference"><a href="#cite_note-6"><span class="cite-bracket">[</span>6<span class="cite-bracket">]</span></a></sup> In practice, there are minimal perfect hashing schemes that use roughly 1.56 bits/key if given enough time.<sup id="cite_ref-RecSplit_7-0" class="reference"><a href="#cite_note-RecSplit-7"><span class="cite-bracket">[</span>7<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-8" class="reference"><a href="#cite_note-8"><span class="cite-bracket">[</span>8<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading3"><h3 id="k-perfect_hashing">k-perfect hashing</h3></div>
<p>A hash function is <span class="texhtml mvar" style="font-style:italic;">k</span>-perfect if at most <span class="texhtml mvar" style="font-style:italic;">k</span> elements from <span class="texhtml mvar" style="font-style:italic;">S</span> are mapped onto the same value in the range. The "hash, displace, and compress" algorithm can be used to construct <span class="texhtml mvar" style="font-style:italic;">k</span>-perfect hash functions by allowing up to <span class="texhtml mvar" style="font-style:italic;">k</span> collisions. The changes necessary to accomplish this are minimal, and are underlined in the adapted pseudocode below:
</p>
<pre>(4) <b>for all</b> i<span style="white-space: nowrap;"> </span>∈[r], in the order from (2), <b>do</b>
(5) <b>for</b> l<span style="white-space: nowrap;"> </span>←<span style="white-space: nowrap;"> </span>1,2,...
(6) <b>repeat</b> forming K<sub>i</sub><span style="white-space: nowrap;"> </span>←<span style="white-space: nowrap;"> </span>{<span class="texhtml">Φ</span><sub>l</sub>(x)|x<span style="white-space: nowrap;"> </span>∈<span style="white-space: nowrap;"> </span>B<sub>i</sub>}
(6) <b>until</b> |K<sub>i</sub>|=|B<sub>i</sub>| <b>and</b> K<sub>i</sub>∩{j|<u>T[j]=k</u>}=<span style="white-space: nowrap;"> </span>∅
(7) <b>let</b> σ(i):= the successful l
(8) <b>for all</b> j<span style="white-space: nowrap;"> </span>∈<span style="white-space: nowrap;"> </span>K<sub>i</sub> <b>set</b> <u>T[j]←T[j]+1</u>
</pre>
<div class="mw-heading mw-heading3"><h3 id="Order_preservation">Order preservation</h3></div>
<p>A minimal perfect hash function <span class="texhtml mvar" style="font-style:italic;">F</span> is <i>order preserving</i> if keys are given in some order <span class="texhtml"><i>a</i><sub>1</sub>, <i>a</i><sub>2</sub>, ..., <i>a</i><sub><i>n</i></sub></span> and for any keys <span class="texhtml"><i>a</i><sub><i>j</i></sub></span> and <span class="texhtml"><i>a</i><sub><i>k</i></sub></span>, <span class="texhtml"><i>j</i> < <i>k</i></span> implies <span class="texhtml"><i>F</i>(<i>a</i><sub><i>j</i></sub>) < F(<i>a</i><sub><i>k</i></sub>)</span>.<sup id="cite_ref-9" class="reference"><a href="#cite_note-9"><span class="cite-bracket">[</span>9<span class="cite-bracket">]</span></a></sup> In this case, the function value is just the position of each key in the sorted ordering of all of the keys. A simple implementation of order-preserving minimal perfect hash functions with constant access time is to use an (ordinary) perfect hash function to store a lookup table of the positions of each key. This solution uses <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(n\log n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>n</mi>
<mi>log</mi>
<mo><!-- --></mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(n\log n)}</annotation>
</semantics>
</math></span><img src="./9d2320768fb54880ca4356e61f60eb02a3f9d9f1.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:10.118ex; height:2.843ex;" alt="{\displaystyle O(n\log n)}" loading="lazy"></span> bits, which is optimal in the setting where the comparison function for the keys may be arbitrary.<sup id="cite_ref-10" class="reference"><a href="#cite_note-10"><span class="cite-bracket">[</span>10<span class="cite-bracket">]</span></a></sup> However, if the keys <span class="texhtml"><i>a</i><sub>1</sub>, <i>a</i><sub>2</sub>, ..., <i>a</i><sub><i>n</i></sub></span> are integers drawn from a universe <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \{1,2,\ldots ,U\}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo fence="false" stretchy="false">{</mo>
<mn>1</mn>
<mo>,</mo>
<mn>2</mn>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<mi>U</mi>
<mo fence="false" stretchy="false">}</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \{1,2,\ldots ,U\}}</annotation>
</semantics>
</math></span><img src="./d2431655ee77a4033df95488cded81c131e07957.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.645ex; height:2.843ex;" alt="{\displaystyle \{1,2,\ldots ,U\}}" loading="lazy"></span>, then it is possible to construct an order-preserving hash function using only <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(n\log \log \log U)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>n</mi>
<mi>log</mi>
<mo><!-- --></mo>
<mi>log</mi>
<mo><!-- --></mo>
<mi>log</mi>
<mo><!-- --></mo>
<mi>U</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(n\log \log \log U)}</annotation>
</semantics>
</math></span><img src="./760a3917c91c59e973214c6f49cc11d493cfbd92.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:17.224ex; height:2.843ex;" alt="{\displaystyle O(n\log \log \log U)}" loading="lazy"></span> bits of space.<sup id="cite_ref-11" class="reference"><a href="#cite_note-11"><span class="cite-bracket">[</span>11<span class="cite-bracket">]</span></a></sup> Moreover, this bound is known to be optimal.<sup id="cite_ref-12" class="reference"><a href="#cite_note-12"><span class="cite-bracket">[</span>12<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Related_constructions">Related constructions</h2></div>
<p>While well-dimensioned hash tables have amortized average O(1) time (amortized average constant time) for lookups, insertions, and deletion, most hash table algorithms suffer from possible worst-case times that take much longer.
A worst-case O(1) time (constant time even in the worst case) would be better for many applications (including <a href="Network_router" class="mw-redirect" title="Network router">network router</a> and <a href="Memory_cache" class="mw-redirect" title="Memory cache">memory caches</a>).<sup id="cite_ref-davis_13-0" class="reference"><a href="#cite_note-davis-13"><span class="cite-bracket">[</span>13<span class="cite-bracket">]</span></a></sup><sup class="reference nowrap"><span title="Page / location: 41">: 41 </span></sup>
</p><p>Few hash table algorithms support worst-case O(1) lookup time (constant lookup time even in the worst case). The few that do include: perfect hashing; <a href="Dynamic_perfect_hashing" title="Dynamic perfect hashing">dynamic perfect hashing</a>; <a href="Cuckoo_hashing" title="Cuckoo hashing">cuckoo hashing</a>; <a href="Hopscotch_hashing" title="Hopscotch hashing">hopscotch hashing</a>; and <a href="Extendible_hashing" title="Extendible hashing">extendible hashing</a>.<sup id="cite_ref-davis_13-1" class="reference"><a href="#cite_note-davis-13"><span class="cite-bracket">[</span>13<span class="cite-bracket">]</span></a></sup><sup class="reference nowrap"><span title="Page / location: 42–69">: 42–69 </span></sup>
</p><p>A simple alternative to perfect hashing, which also allows dynamic updates, is <a href="Cuckoo_hashing" title="Cuckoo hashing">cuckoo hashing</a>. This scheme maps keys to two or more locations within a range (unlike perfect hashing which maps each key to a single location) but does so in such a way that the keys can be assigned one-to-one to locations to which they have been mapped. Lookups with this scheme are slower, because multiple locations must be checked, but nevertheless take constant worst-case time.<sup id="cite_ref-14" class="reference"><a href="#cite_note-14"><span class="cite-bracket">[</span>14<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */
.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}
/* end https://en.wikipedia.org/ */
</style><div class="reflist reflist-columns references-column-width" style="column-width: 30em;">
<ol class="references">
<li id="cite_note-DynamicPerfectHashing-1"><span class="mw-cite-backlink">^ <a href="#cite_ref-DynamicPerfectHashing_1-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-DynamicPerfectHashing_1-1"><sup><i><b>b</b></i></sup></a></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}
/* end https://en.wikipedia.org/ */
</style><cite id="CITEREFDietzfelbingerKarlinMehlhornMeyer_auf_der_Heide1994" class="citation cs2">Dietzfelbinger, Martin; <a href="Anna_Karlin" title="Anna Karlin">Karlin, Anna</a>; <a href="Kurt_Mehlhorn" title="Kurt Mehlhorn">Mehlhorn, Kurt</a>; Meyer auf der Heide, Friedhelm; Rohnert, Hans; <a href="Robert_Tarjan" title="Robert Tarjan">Tarjan, Robert E.</a> (1994), "Dynamic perfect hashing: upper and lower bounds", <i><a href="SIAM_Journal_on_Computing" title="SIAM Journal on Computing">SIAM Journal on Computing</a></i>, <b>23</b> (4): <span class="nowrap">738–</span>761, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1137%2FS0097539791194094">10.1137/S0097539791194094</a>, <a href="MR_(identifier)" class="mw-redirect" title="MR (identifier)">MR</a> <a rel="nofollow" class="external text" href="https://mathscinet.ams.org/mathscinet-getitem?mr=1283572">1283572</a></cite>.</span>
</li>
<li id="cite_note-inventor-2"><span class="mw-cite-backlink">^ <a href="#cite_ref-inventor_2-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-inventor_2-1"><sup><i><b>b</b></i></sup></a> <a href="#cite_ref-inventor_2-2"><sup><i><b>c</b></i></sup></a> <a href="#cite_ref-inventor_2-3"><sup><i><b>d</b></i></sup></a> <a href="#cite_ref-inventor_2-4"><sup><i><b>e</b></i></sup></a></span> <span class="reference-text"><cite id="CITEREFFredmanKomlósSzemerédi1984" class="citation cs2"><a href="Michael_Fredman" title="Michael Fredman">Fredman, Michael L.</a>; <a href="J%C3%A1nos_Koml%C3%B3s_(mathematician)" title="János Komlós (mathematician)">Komlós, János</a>; <a href="Endre_Szemer%C3%A9di" title="Endre Szemerédi">Szemerédi, Endre</a> (1984), "Storing a Sparse Table with <span class="texhtml"><i>O</i>(1)</span> Worst Case Access Time", <i><a href="Journal_of_the_ACM" title="Journal of the ACM">Journal of the ACM</a></i>, <b>31</b> (3): 538, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://doi.org/10.1145%2F828.1884">10.1145/828.1884</a></span>, <a href="MR_(identifier)" class="mw-redirect" title="MR (identifier)">MR</a> <a rel="nofollow" class="external text" href="https://mathscinet.ams.org/mathscinet-getitem?mr=0819156">0819156</a>, <a href="S2CID_(identifier)" class="mw-redirect" title="S2CID (identifier)">S2CID</a> <a rel="nofollow" class="external text" href="https://api.semanticscholar.org/CorpusID:5399743">5399743</a></cite></span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-3">^</a></b></span> <span class="reference-text"><cite id="CITEREFLuPrabhakarBonomi2006" class="citation cs2">Lu, Yi; Prabhakar, Balaji; Bonomi, Flavio (2006), "Perfect Hashing for Network Applications", <i>2006 IEEE International Symposium on Information Theory</i>, pp. <span class="nowrap">2774–</span>2778, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1109%2FISIT.2006.261567">10.1109/ISIT.2006.261567</a>, <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>1-4244-0505-X</bdi>, <a href="S2CID_(identifier)" class="mw-redirect" title="S2CID (identifier)">S2CID</a> <a rel="nofollow" class="external text" href="https://api.semanticscholar.org/CorpusID:1494710">1494710</a></cite></span>
</li>
<li id="cite_note-CHD-4"><span class="mw-cite-backlink">^ <a href="#cite_ref-CHD_4-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-CHD_4-1"><sup><i><b>b</b></i></sup></a> <a href="#cite_ref-CHD_4-2"><sup><i><b>c</b></i></sup></a> <a href="#cite_ref-CHD_4-3"><sup><i><b>d</b></i></sup></a> <a href="#cite_ref-CHD_4-4"><sup><i><b>e</b></i></sup></a> <a href="#cite_ref-CHD_4-5"><sup><i><b>f</b></i></sup></a> <a href="#cite_ref-CHD_4-6"><sup><i><b>g</b></i></sup></a> <a href="#cite_ref-CHD_4-7"><sup><i><b>h</b></i></sup></a> <a href="#cite_ref-CHD_4-8"><sup><i><b>i</b></i></sup></a> <a href="#cite_ref-CHD_4-9"><sup><i><b>j</b></i></sup></a> <a href="#cite_ref-CHD_4-10"><sup><i><b>k</b></i></sup></a> <a href="#cite_ref-CHD_4-11"><sup><i><b>l</b></i></sup></a></span> <span class="reference-text"><cite id="CITEREFBelazzouguiBotelhoDietzfelbinger2009" class="citation cs2">Belazzougui, Djamal; Botelho, Fabiano C.; Dietzfelbinger, Martin (2009), <a rel="nofollow" class="external text" href="https://cmph.sourceforge.net/papers/esa09.pdf">"Hash, displace, and compress"</a> <span class="cs1-format">(PDF)</span>, <a rel="nofollow" class="external text" href="https://cmph.sourceforge.net/papers/esa09.pdf"><i>Algorithms - ESA 2009</i></a> <span class="cs1-format">(PDF)</span>, <a href="Lecture_Notes_in_Computer_Science" title="Lecture Notes in Computer Science">Lecture Notes in Computer Science</a>, vol. 5757, Berlin: Springer, pp. <span class="nowrap">682–</span>693, <a href="CiteSeerX_(identifier)" class="mw-redirect" title="CiteSeerX (identifier)">CiteSeerX</a> <span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.568.130">10.1.1.568.130</a></span>, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1007%2F978-3-642-04128-0_61">10.1007/978-3-642-04128-0_61</a>, <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>978-3-642-04127-3</bdi>, <a href="MR_(identifier)" class="mw-redirect" title="MR (identifier)">MR</a> <a rel="nofollow" class="external text" href="https://mathscinet.ams.org/mathscinet-getitem?mr=2557794">2557794</a></cite>.</span>
</li>
<li id="cite_note-5"><span class="mw-cite-backlink"><b><a href="#cite_ref-5">^</a></b></span> <span class="reference-text"><cite id="CITEREFFredmanKomlós1984" class="citation cs2"><a href="Michael_Fredman" title="Michael Fredman">Fredman, Michael L.</a>; <a href="J%C3%A1nos_Koml%C3%B3s_(mathematician)" title="János Komlós (mathematician)">Komlós, János</a> (1984), "On the size of separating systems and families of perfect hash functions", <i><a href="SIAM_Journal_on_Algebraic_and_Discrete_Methods" class="mw-redirect" title="SIAM Journal on Algebraic and Discrete Methods">SIAM Journal on Algebraic and Discrete Methods</a></i>, <b>5</b> (1): <span class="nowrap">61–</span>68, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1137%2F0605009">10.1137/0605009</a>, <a href="MR_(identifier)" class="mw-redirect" title="MR (identifier)">MR</a> <a rel="nofollow" class="external text" href="https://mathscinet.ams.org/mathscinet-getitem?mr=0731857">0731857</a></cite>.</span>
</li>
<li id="cite_note-6"><span class="mw-cite-backlink"><b><a href="#cite_ref-6">^</a></b></span> <span class="reference-text"><cite id="CITEREFHagerupTholey2001" class="citation cs2">Hagerup, Torben; Tholey, Torsten (2001), <span class="id-lock-subscription" title="Paid subscription required"><a rel="nofollow" class="external text" href="https://dx.doi.org/10.1007/3-540-44693-1_28">"Efficient Minimal Perfect Hashing in Nearly Minimal Space"</a></span>, <i>STACS 2001</i>, Berlin, Heidelberg: Springer Berlin Heidelberg, pp. <span class="nowrap">317–</span>326, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1007%2F3-540-44693-1_28">10.1007/3-540-44693-1_28</a>, <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>978-3-540-41695-1</bdi><span class="reference-accessdate">, retrieved <span class="nowrap">2023-11-12</span></span></cite></span>
</li>
<li id="cite_note-RecSplit-7"><span class="mw-cite-backlink"><b><a href="#cite_ref-RecSplit_7-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFEspositoMueller_GrafVigna2020" class="citation cs2">Esposito, Emmanuel; Mueller Graf, Thomas; Vigna, Sebastiano (2020), "RecSplit: Minimal Perfect Hashing via Recursive Splitting", <i>2020 Proceedings of the Symposium on Algorithm Engineering and Experiments (ALENEX)</i>, <a href="Proceedings" class="mw-redirect" title="Proceedings">Proceedings</a>, pp. <span class="nowrap">175–</span>185, <a href="ArXiv_(identifier)" class="mw-redirect" title="ArXiv (identifier)">arXiv</a>:<span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://arxiv.org/abs/1910.06416">1910.06416</a></span>, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://doi.org/10.1137%2F1.9781611976007.14">10.1137/1.9781611976007.14</a></span></cite>.</span>
</li>
<li id="cite_note-8"><span class="mw-cite-backlink"><b><a href="#cite_ref-8">^</a></b></span> <span class="reference-text"><a rel="nofollow" class="external text" href="https://github.com/iwiwi/minimal-perfect-hash">minimal-perfect-hash (GitHub)</a></span>
</li>
<li id="cite_note-9"><span class="mw-cite-backlink"><b><a href="#cite_ref-9">^</a></b></span> <span class="reference-text"><cite id="CITEREFJenkins2009" class="citation cs2">Jenkins, Bob (14 April 2009), "order-preserving minimal perfect hashing", in Black, Paul E. (ed.), <a rel="nofollow" class="external text" href="https://xlinux.nist.gov/dads/HTML/orderPreservMinPerfectHash.html"><i>Dictionary of Algorithms and Data Structures</i></a>, U.S. National Institute of Standards and Technology<span class="reference-accessdate">, retrieved <span class="nowrap">2013-03-05</span></span></cite></span>
</li>
<li id="cite_note-10"><span class="mw-cite-backlink"><b><a href="#cite_ref-10">^</a></b></span> <span class="reference-text"><cite id="CITEREFFoxChenDaoudHeath1991" class="citation cs2">Fox, Edward A.; Chen, Qi Fan; Daoud, Amjad M.; Heath, Lenwood S. (July 1991), <a rel="nofollow" class="external text" href="http://eprints.cs.vt.edu/archive/00000248/01/TR-91-01.pdf">"Order-preserving minimal perfect hash functions and information retrieval"</a> <span class="cs1-format">(PDF)</span>, <i>ACM Transactions on Information Systems</i>, <b>9</b> (3), New York, NY, USA: ACM: <span class="nowrap">281–</span>308, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1145%2F125187.125200">10.1145/125187.125200</a>, <a href="S2CID_(identifier)" class="mw-redirect" title="S2CID (identifier)">S2CID</a> <a rel="nofollow" class="external text" href="https://api.semanticscholar.org/CorpusID:53239140">53239140</a></cite>.</span>
</li>
<li id="cite_note-11"><span class="mw-cite-backlink"><b><a href="#cite_ref-11">^</a></b></span> <span class="reference-text"><cite id="CITEREFBelazzouguiBoldiPaghVigna2008" class="citation cs2">Belazzougui, Djamal; Boldi, Paolo; <a href="Rasmus_Pagh" title="Rasmus Pagh">Pagh, Rasmus</a>; Vigna, Sebastiano (November 2008), "Theory and practice of monotone minimal perfect hashing", <i>Journal of Experimental Algorithmics</i>, <b>16</b>, Art. no. 3.2, 26pp, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1145%2F1963190.2025378">10.1145/1963190.2025378</a>, <a href="S2CID_(identifier)" class="mw-redirect" title="S2CID (identifier)">S2CID</a> <a rel="nofollow" class="external text" href="https://api.semanticscholar.org/CorpusID:2367401">2367401</a></cite>.</span>
</li>
<li id="cite_note-12"><span class="mw-cite-backlink"><b><a href="#cite_ref-12">^</a></b></span> <span class="reference-text"><cite id="CITEREFAssadiFarach-ColtonKuszmaul2023" class="citation cs2">Assadi, Sepehr; Farach-Colton, Martín; Kuszmaul, William (January 2023), <a rel="nofollow" class="external text" href="https://dx.doi.org/10.1137/1.9781611977554.ch20">"Tight Bounds for Monotone Minimal Perfect Hashing"</a>, <i>Proceedings of the 2023 Annual ACM-SIAM Symposium on Discrete Algorithms (SODA)</i>, Philadelphia, PA: Society for Industrial and Applied Mathematics, pp. <span class="nowrap">456–</span>476, <a href="ArXiv_(identifier)" class="mw-redirect" title="ArXiv (identifier)">arXiv</a>:<span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://arxiv.org/abs/2207.10556">2207.10556</a></span>, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1137%2F1.9781611977554.ch20">10.1137/1.9781611977554.ch20</a>, <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>978-1-61197-755-4</bdi><span class="reference-accessdate">, retrieved <span class="nowrap">2023-04-27</span></span></cite></span>
</li>
<li id="cite_note-davis-13"><span class="mw-cite-backlink">^ <a href="#cite_ref-davis_13-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-davis_13-1"><sup><i><b>b</b></i></sup></a></span> <span class="reference-text">
Timothy A. Davis.
<a rel="nofollow" class="external text" href="https://www.cs.wm.edu/~tadavis/cs303/ch05sm.pdf">"Chapter 5 Hashing"</a>: subsection "Hash Tables with Worst-Case O(1) Access"</span>
</li>
<li id="cite_note-14"><span class="mw-cite-backlink"><b><a href="#cite_ref-14">^</a></b></span> <span class="reference-text"><cite id="CITEREFPaghRodler2004" class="citation cs2"><a href="Rasmus_Pagh" title="Rasmus Pagh">Pagh, Rasmus</a>; Rodler, Flemming Friche (2004), "Cuckoo hashing", <i>Journal of Algorithms</i>, <b>51</b> (2): <span class="nowrap">122–</span>144, <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1016%2Fj.jalgor.2003.12.002">10.1016/j.jalgor.2003.12.002</a>, <a href="MR_(identifier)" class="mw-redirect" title="MR (identifier)">MR</a> <a rel="nofollow" class="external text" href="https://mathscinet.ams.org/mathscinet-getitem?mr=2050140">2050140</a></cite>.</span>
</li>
</ol></div>
<div class="mw-heading mw-heading2"><h2 id="Further_reading">Further reading</h2></div>
<ul><li>Richard J. Cichelli. <i>Minimal Perfect Hash Functions Made Simple</i>, Communications of the ACM, Vol. 23, Number 1, January 1980.</li>
<li><a href="Thomas_H._Cormen" title="Thomas H. Cormen">Thomas H. Cormen</a>, <a href="Charles_E._Leiserson" title="Charles E. Leiserson">Charles E. Leiserson</a>, <a href="Ronald_L._Rivest" class="mw-redirect" title="Ronald L. Rivest">Ronald L. Rivest</a>, and <a href="Clifford_Stein" title="Clifford Stein">Clifford Stein</a>. <i><a href="Introduction_to_Algorithms" title="Introduction to Algorithms">Introduction to Algorithms</a></i>, Third Edition. MIT Press, 2009. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>978-0262033848</bdi>. Section 11.5: Perfect hashing, pp. 267, 277–282.</li>
<li>Fabiano C. Botelho, <a href="Rasmus_Pagh" title="Rasmus Pagh">Rasmus Pagh</a> and Nivio Ziviani. <a rel="nofollow" class="external text" href="https://arxiv.org/abs/cs/0702159">"Perfect Hashing for Data Management Applications"</a>.</li>
<li>Fabiano C. Botelho and <a href="Nivio_Ziviani" title="Nivio Ziviani">Nivio Ziviani</a>. <a rel="nofollow" class="external text" href="http://homepages.dcc.ufmg.br/~nivio/papers/cikm07.pdf">"External perfect hashing for very large key sets"</a>. 16th ACM Conference on Information and Knowledge Management (CIKM07), Lisbon, Portugal, November 2007.</li>
<li>Djamal Belazzougui, Paolo Boldi, <a href="Rasmus_Pagh" title="Rasmus Pagh">Rasmus Pagh</a>, and Sebastiano Vigna. <a rel="nofollow" class="external text" href="https://web.archive.org/web/20140125080021/http://vigna.dsi.unimi.it/ftp/papers/MonotoneMinimalPerfectHashing.pdf">"Monotone minimal perfect hashing: Searching a sorted table with O(1) accesses"</a>. In Proceedings of the 20th Annual ACM-SIAM Symposium On Discrete Mathematics (SODA), New York, 2009. ACM Press.</li>
<li>Marshall D. Brain and Alan L. Tharp. "Near-perfect Hashing of Large Word Sets". Software—Practice and Experience, vol. 19(10), 967-078, October 1989. John Wiley & Sons.</li>
<li>Douglas C. Schmidt, <a rel="nofollow" class="external text" href="http://www.dre.vanderbilt.edu/~schmidt/PDF/gperf.pdf">GPERF: A Perfect Hash Function Generator</a>, C++ Report, SIGS, Vol. 10, No. 10, November/December, 1998.</li>
<li>Hans-Peter Lehmann, Thomas Mueller, Rasmus Pagh, Giulio Ermanno Pibiri, Peter Sanders, Sebastiano Vigna, Stefan Walzer, "Modern Minimal Perfect Hashing: A Survey", <a href="ArXiv_(identifier)" class="mw-redirect" title="ArXiv (identifier)">arXiv</a>:<span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://arxiv.org/abs/2506.06536">2506.06536</a></span>, June 2025. Discusses post-1997 developments in the field.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="External_links">External links</h2></div>
<ul><li><a rel="nofollow" class="external text" href="https://www.gnu.org/software/gperf/">gperf</a> is an <a href="Open_source" title="Open source">open source</a> C and C++ perfect hash generator (very fast, but only works for small sets)</li>
<li><a rel="nofollow" class="external text" href="http://burtleburtle.net/bob/hash/perfect.html">Minimal Perfect Hashing (bob algorithm)</a> by Bob Jenkins</li>
<li><a rel="nofollow" class="external text" href="https://cmph.sourceforge.net/index.html">cmph</a>: C Minimal Perfect Hashing Library, open source implementations for many (minimal) perfect hashes (works for big sets)</li>
<li><a rel="nofollow" class="external text" href="http://sux.di.unimi.it/">Sux4J</a>: open source monotone minimal perfect hashing in Java</li>
<li><a rel="nofollow" class="external text" href="https://web.archive.org/web/20130729211948/http://www.dupuis.me/node/9">MPHSharp</a>: perfect hashing methods in C#</li>
<li><a rel="nofollow" class="external text" href="https://github.com/rizkg/BBHash">BBHash</a>: minimal perfect hash function in header-only C++</li>
<li><a rel="nofollow" class="external text" href="https://github.com/rurban/Perfect-Hash">Perfect::Hash</a>, perfect hash generator in Perl that makes C code. Has a "prior art" section worth looking at.</li></ul></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-06-20" href="https://en.wikipedia.org/wiki/?title=Perfect_hash_function&oldid=1296432605">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
</body></html>